ConfigMap 很好用,但有一種東西不能放進去,就是密碼。ConfigMap 的內容任何人 get 一下就是明文,而且那份 YAML 通常會進 git,等於把密碼一起推上去
今天要來看 Secret,先建一組假的資料庫帳密
secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: db-cred
namespace: ithome-lab
type: Opaque
stringData:
DB_USER: ithome
DB_PASSWORD: not-a-real-password
type 寫 Opaque 就是一般用途的 Secret,另外還有專門給 Docker registry 憑證、TLS 憑證用的類型,各有各的格式要求
這裡用的是 stringData,可以直接寫明文,K8s 收下之後會自己幫你編碼。另一種寫法是用 data,那個欄位要求你先把值轉成 base64 再貼進去,寫起來麻煩而且會看不懂自己填了什麼
套用之後看看
kubectl apply -f manifests/base/secret.yaml
kubectl get secret db-cred -n ithome-lab -o yaml

那串亂碼只是 base64 編碼,不是加密。只要能對這個 namespace 下 get secret,就能直接解回明文
驗證一下,先把值撈出來
kubectl get secret db-cred -n ithome-lab -o jsonpath="{.data.DB_PASSWORD}"

然後在 PowerShell 解碼
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("密碼"))

Secret 防止不小心印出來、被順手看到這一類的意外,真正決定誰能讀要靠 RBAC,儲存層的加密要另外開。不把 Secret 寫進 git,改用 Sealed Secrets 或外部的金鑰服務,這我還不熟.w.
接下來把它注入到 Pod。改 deployment.yaml,在 container 底下加一段
envFrom:
- secretRef:
name: db-cred
envFrom 是把整個 Secret 的每個鍵都變成環境變數。如果只想挑其中一個,寫法是這樣
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-cred
key: DB_PASSWORD
我選上面,因為比較短.w.
套用然後進去看
kubectl apply -f manifests/base
kubectl rollout status deployment/web -n ithome-lab
kubectl exec deploy/web -n ithome-lab -- env

環境變數確實進去了。順便注意一下,密碼就這樣大剌剌印在終端機上,剛剛說的那個不小心印出來,講的就是這個畫面
另一種注入方式是掛成檔案,寫法跟 Day 11 的 ConfigMap 幾乎一樣,只是把 configMap 換成 secret
volumes:
- name: db-cred
secret:
secretName: db-cred
掛進去之後每個鍵會變成一個檔案。要用哪一種取決於程式怎麼讀設定,讀環境變數的就用 envFrom,讀設定檔的就用 volume
secret.yaml 裡面寫的是明文,這個檔案不該進 git。要在 .gitignore 加一行忽略,另外存一份 secret.example.yaml 只留欄位不留值,之後自己或別人重建環境的時候才知道要填什麼
明天見 :D
